/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.gzchengguo.cn
* 注意：
* 本软件为www.gzchengguo.cn开发研制，未经购买不得商用
* 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
* 一经发现盗用、分享等行为，将追究法律责任，后果自负
*/
package link.chengguo.orangemall.modules.user.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import link.chengguo.orangemall.api.OrangeException;
import link.chengguo.orangemall.common.service.impl.BaseServiceImpl;
import link.chengguo.orangemall.common.utils.QueryHelpPlus;
import link.chengguo.orangemall.dozer.service.IGenerator;
import link.chengguo.orangemall.enums.BillDetailEnum;
import link.chengguo.orangemall.enums.OrderInfoEnum;
import link.chengguo.orangemall.enums.PayTypeEnum;
import link.chengguo.orangemall.event.TemplateBean;
import link.chengguo.orangemall.event.TemplateEvent;
import link.chengguo.orangemall.event.TemplateListenEnum;
import link.chengguo.orangemall.modules.user.domain.OrangeUser;
import link.chengguo.orangemall.modules.user.domain.OrangeUserRecharge;
import link.chengguo.orangemall.modules.user.service.OrangeUserBillService;
import link.chengguo.orangemall.modules.user.service.OrangeUserRechargeService;
import link.chengguo.orangemall.modules.user.service.dto.OrangeUserRechargeDto;
import link.chengguo.orangemall.modules.user.service.dto.OrangeUserRechargeQueryCriteria;
import link.chengguo.orangemall.modules.user.service.mapper.UserMapper;
import link.chengguo.orangemall.modules.user.service.mapper.UserRechargeMapper;
import link.chengguo.orangemall.utils.FileUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;



/**
* @author chengguo
* @date 2020-05-12
*/
@SuppressWarnings("unchecked")
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class OrangeUserRechargeServiceImpl extends BaseServiceImpl<UserRechargeMapper, OrangeUserRecharge> implements OrangeUserRechargeService {
    @Autowired
    private IGenerator generator;

    @Autowired
    private UserRechargeMapper orangeUserRechargeMapper;
    @Autowired
    private OrangeUserBillService billService;

    @Autowired
    private UserMapper orangeUserMapper;

    @Autowired
    private ApplicationEventPublisher publisher;


    @Override
    public void updateRecharge(OrangeUserRecharge userRecharge) {
        OrangeUser user = orangeUserMapper.selectById(userRecharge.getUid());

        //修改状态
        userRecharge.setPaid(OrderInfoEnum.PAY_STATUS_1.getValue());
        userRecharge.setPayTime(new Date());
        orangeUserRechargeMapper.updateById(userRecharge);

        //最终充值金额
        BigDecimal newPrice = NumberUtil.add(userRecharge.getPrice(),user.getNowMoney());


        //增加流水
        billService.income(userRecharge.getUid(),"用户余额充值", BillDetailEnum.CATEGORY_1.getValue(),
                BillDetailEnum.TYPE_1.getValue(),userRecharge.getPrice().doubleValue(),newPrice.doubleValue(),
                "成功充值余额"+userRecharge.getPrice(),userRecharge.getId().toString());


        //update 余额
        user.setNowMoney(newPrice);
        orangeUserMapper.updateById(user);

        //模板消息发布事件
        TemplateBean templateBean = TemplateBean.builder()
                .time(DateUtil.formatTime(userRecharge.getPayTime()))
                .price(userRecharge.getPrice().toString())
                .orderId(userRecharge.getOrderId())
                .uid(userRecharge.getUid())
                .templateType(TemplateListenEnum.TYPE_4.getValue())
                .build();
        publisher.publishEvent(new TemplateEvent(this, templateBean));

    }

    @Override
    public OrangeUserRecharge getInfoByOrderId(String orderId) {
        OrangeUserRecharge userRecharge = new OrangeUserRecharge();
        userRecharge.setOrderId(orderId);

        return orangeUserRechargeMapper.selectOne(Wrappers.query(userRecharge));
    }

    /**
     * 添加充值记录
     * @param user 用户
     * @param price 充值金额
     * @param paidPrice 赠送金额
     */
    @Override
    public String addRecharge(OrangeUser user, String price, String paidPrice) {
        if(StrUtil.isBlank(price) || StrUtil.isBlank(paidPrice)){
            throw new OrangeException("参数非法");
        }
        OrangeUserRecharge orangeUserRecharge = new OrangeUserRecharge();

        String orderSn = IdUtil.getSnowflake(0,0).nextIdStr();

        orangeUserRecharge.setNickname(user.getNickname());
        orangeUserRecharge.setOrderId(orderSn);
        orangeUserRecharge.setUid(user.getUid());
        orangeUserRecharge.setPrice(new BigDecimal(price));
        orangeUserRecharge.setGivePrice(new BigDecimal(paidPrice));
        orangeUserRecharge.setRechargeType(PayTypeEnum.WEIXIN.getValue());
        orangeUserRecharge.setPaid(OrderInfoEnum.PAY_STATUS_0.getValue());

        orangeUserRechargeMapper.insert(orangeUserRecharge);

        return orderSn;

    }



    //==========================================================================//

    @Override
    //@Cacheable
    public Map<String, Object> queryAll(OrangeUserRechargeQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<OrangeUserRecharge> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", generator.convert(page.getList(), OrangeUserRechargeDto.class));
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    //@Cacheable
    public List<OrangeUserRecharge> queryAll(OrangeUserRechargeQueryCriteria criteria){
        return baseMapper.selectList(QueryHelpPlus.getPredicate(OrangeUserRecharge.class, criteria));
    }


    @Override
    public void download(List<OrangeUserRechargeDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OrangeUserRechargeDto orangeUserRecharge : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("充值用户UID", orangeUserRecharge.getUid());
            map.put("订单号", orangeUserRecharge.getOrderId());
            map.put("充值金额", orangeUserRecharge.getPrice());
            map.put("充值类型", orangeUserRecharge.getRechargeType());
            map.put("是否充值", orangeUserRecharge.getPaid());
            map.put("充值支付时间", orangeUserRecharge.getPayTime());
            map.put("退款金额", orangeUserRecharge.getRefundPrice());
            map.put("昵称", orangeUserRecharge.getNickname());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}
